<?php
/**
 * @package Autogenerator for Joomla!
 * @version 3.0.0
 * @author Truong Cong Duc <truongcongduc4@gmail.com>
 * @link autogenerator.blogspot.com
 * @copyright (c) 2013, Truong Cong Duc
 * @license GNU General Public License version 2 or later; see LICENSE.txt
 */

defined('_JEXEC') or die;

require_once JPATH_COMPONENT_ADMINISTRATOR . '/helpers/autogenerator.php';

class AutogeneratorModelField extends JModelAdmin {

    protected $text_prefix = 'COM_AUTOGENERATOR';

    public function getForm($data = array(), $loadData = true) {
        $form = $this->loadForm('com_autogenerator.field', 'field', array('control' => 'jform', 'load_data' => $loadData));

        if (empty($form)) {
            return false;
        }

        return $form;
    }

    public function getTable($type = 'Field', $prefix = 'AutogeneratorTable', $config = array()) {
        return JTable::getInstance($type, $prefix, $config);
    }

    protected function loadFormData() {
        $data = JFactory::getApplication()->getUserState('com_autogenerator.edit.field.data', array());

        if (empty($data)) {
            $data = $this->getItem();
        }

        return $data;
    }

    protected function getReorderConditions($table) {
        $condition = array();
        $condition[] = 'table_id = ' . (int) $table->table_id;
        return $condition;
    }

    protected function prepareTable($table) {
        if (empty($table->id)) {
            if (empty($table->ordering)) {
                $db = JFactory::getDbo();
                $db->setQuery('SELECT MAX(ordering) FROM #__auto_field');
                $max = $db->loadResult();

                $table->ordering = $max + 1;
            }
        }
    }

    /**
     * For ajax. Change the status of the field.
     * @param int $iFieldId
     * @return int|string 
     */
    public function changeStatus($iFieldId) {
        $iKey = (int) $iFieldId;
        if ($iKey < 1) {
            return JText::_('COM_AUTOGENERATOR_FIELD_AJAX_ERROR_MESSAGE_FIELD_NOT_VALID');
        }

        $oTable = $this->getTable();

        // Allow an exception to be thrown.
        try {
            // Load the row if saving an existing record.
            if ($iKey > 0) {
                if (!$oTable->load($iKey)) {
                    return JText::_('COM_AUTOGENERATOR_FIELD_AJAX_ERROR_MESSAGE_FIELD_NOT_VALID');
                }
            }

            if (intval($oTable->id) == 0) {
                return JText::_('COM_AUTOGENERATOR_FIELD_AJAX_ERROR_MESSAGE_FIELD_NOT_VALID');
            }

            // Change the status.
            if ($oTable->status == 1)
                $oTable->status = 0;
            else
                $oTable->status = 1;

            // Prepare the row for saving
            $this->prepareTable($oTable);

            // Check the data.
            if (!$oTable->check()) {
                return $oTable->getError();
            }

            // Store the data.
            if (!$oTable->store()) {
                return $oTable->getError();
            }

            // Clean the cache.
            $this->cleanCache();
        } catch (Exception $e) {
            return $e->getMessage();
        }

        return $oTable->status;
    }

    /**
     * For ajax. Allow edit in list.
     * @param int $iFieldId
     * @return int|string 
     */
    public function allowEditInList($iFieldId) {
        $iKey = (int) $iFieldId;
        if ($iKey < 1) {
            return JText::_('COM_AUTOGENERATOR_FIELD_AJAX_ERROR_MESSAGE_FIELD_NOT_VALID');
        }

        $oTable = $this->getTable();

        // Allow an exception to be thrown.
        try {
            // Load the row if saving an existing record.
            if ($iKey > 0) {
                if (!$oTable->load($iKey)) {
                    return JText::_('COM_AUTOGENERATOR_FIELD_AJAX_ERROR_MESSAGE_FIELD_NOT_VALID');
                }
            }

            if (intval($oTable->id) == 0) {
                return JText::_('COM_AUTOGENERATOR_FIELD_AJAX_ERROR_MESSAGE_FIELD_NOT_VALID');
            }

            // Change the status.
            if ($oTable->allow_edit_in_list == 1)
                $oTable->allow_edit_in_list = 0;
            else
                $oTable->allow_edit_in_list = 1;

            // Prepare the row for saving
            $this->prepareTable($oTable);

            // Check the data.
            if (!$oTable->check()) {
                return $oTable->getError();
            }

            // Store the data.
            if (!$oTable->store()) {
                return $oTable->getError();
            }

            // Clean the cache.
            $this->cleanCache();
        } catch (Exception $e) {
            return $e->getMessage();
        }

        return $oTable->allow_edit_in_list;
    }

    public function editXmlTypeInline($iFieldId, $iXmlTypeId) {
        $iKey = (int) $iFieldId;
        if ($iKey < 1) {
            return JText::_('COM_AUTOGENERATOR_FIELD_AJAX_ERROR_MESSAGE_FIELD_NOT_VALID');
        }

        $oTable = $this->getTable();

        // Allow an exception to be thrown.
        try {
            // Load the row if saving an existing record.
            if ($iKey > 0) {
                if (!$oTable->load($iKey)) {
                    return JText::_('COM_AUTOGENERATOR_FIELD_AJAX_ERROR_MESSAGE_FIELD_NOT_VALID');
                }
            }

            if (intval($oTable->id) == 0) {
                return JText::_('COM_AUTOGENERATOR_FIELD_AJAX_ERROR_MESSAGE_FIELD_NOT_VALID');
            }

            $oTable->xml_type_id = $iXmlTypeId;

            // Prepare the row for saving
            $this->prepareTable($oTable);

            // Check the data.
            if (!$oTable->check()) {
                return $oTable->getError();
            }

            // Store the data.
            if (!$oTable->store()) {
                return $oTable->getError();
            }

            // Clean the cache.
            $this->cleanCache();
        } catch (Exception $e) {
            return $e->getMessage();
        }

        return 1;
    }

    public function getPrimaryKeyField($iTableId) {
        $db = JFactory::getDbo();
        $query = $db->getQuery(true);

        $query->select('af.*')
                ->from('#__auto_field AS af')
                ->where('af.table_id = ' . (int) $iTableId)
                ->where('af.sql_key = "PRI"')
                ->where('af.sql_extra = "auto_increment"');

        $db->setQuery($query);

        try {
            $aField = $db->loadObject();
        } catch (RuntimeException $e) {
            JError::raiseWarning(500, $e->getMessage);
        }

        return $aField;
    }

    public function detectXMLType($iFieldId) {
        $oField = $this->getItem($iFieldId);

        if ($oField->id < 1) {
            return 0;
        }

        $aTypes = array(
            'int' => 'text',
            'text' => 'editor',
            'varchar' => 'text',
            'mediumtext' => 'editor',
            'datetime' => 'calendar');

        foreach ($aTypes as $sKey => $sValue) {
            $iResult = 0;

            if ($oField->sql_key == 'PRI' && strtolower($oField->sql_extra) == 'auto_increment') {
                $iResult = AutogeneratorHelper::searchXMLType('hidden');
            } else {
                $bResult = strpos(strtolower($oField->sql_type), $sKey);
                if ($bResult !== false) {
                    $iResult = AutogeneratorHelper::searchXMLType($sValue);
                }
            }

            if ($iResult > 0) {
                return $iResult;
            }
        }

        return AutogeneratorHelper::searchXMLType('text');
    }

    public function getItem($pk = null) {
        $oModelTable = JModelLegacy::getInstance('Table', 'AutogeneratorModel');
        $oModelXMLType = JModelLegacy::getInstance('Xml_type', 'AutogeneratorModel');
        $oModelXMLElements = JModelLegacy::getInstance('Xml_elements', 'AutogeneratorModel');
        $oModelComponent = JModelLegacy::getInstance('Component', 'AutogeneratorModel');

        $oItem = parent::getItem($pk);

        $oItem->table_title = '';
        $oItem->xml_type_title = '';
        $oItem->sql_export = '';
        $oItem->xml_export = '';
        if ($oItem->id > 0) {
            $oTable = $oModelTable->getItem($oItem->table_id);
            $oXMLType = $oModelXMLType->getItem($oItem->xml_type_id);
            $oComponent = $oModelComponent->getItem($oTable->component_id);

            $oItem->table_title = $oTable->id > 0 ? $oTable->title : '';
            $oItem->xml_type_title = $oXMLType->id > 0 ? $oXMLType->title : '';
            $oItem->sql_export = '`' . $oItem->sql_field . '` ' . $oItem->sql_type . ($oItem->sql_null == 'NO' ? ' NOT NULL' : '') . (empty($oItem->sql_default) ? '' : ' DEFAULT "' . $oItem->sql_default . '"') . ($oItem->sql_key == 'PRI' ? ' PRIMARY KEY' : '') . (empty($oItem->sql_extra) & $oItem->sql_extra == 'auto_increment' ? '' : ' ' . strtoupper($oItem->sql_extra));

            $aXMLElements = $oModelXMLElements->getXMLElements($oItem->xml_type_id);

            $sTemp = strtoupper($oComponent->title) . '_' . strtoupper($oTable->title) . '_FIELD_' . strtoupper($oItem->sql_field);
            $aXMLText = array(
                'name="' . $oItem->sql_field . '"',
                'type="' . strtolower($oXMLType->title) . '"',
                'label="COM_' . $sTemp . '_LABEL"',
                'description="COM_' . $sTemp . '_DESC"'
            );

            foreach ($aXMLElements as $aXMLElement) {
                $aXMLText[] = $aXMLElement->title . '="' . (empty($aXMLElement->custom) ? $aXMLElement->default : $aXMLElement->custom) . '"';
            }

            if ($oXMLType->type == ConstantHelper::$_XML_TYPE_ITEM) {
                $sXMLExport = '<field ' . implode(' ', $aXMLText) . ' />';
            } else {
                $sXMLExport = '<field ' . implode(' ', $aXMLText) . ' ><option value="">JOPTION_USE_DEFAULT</option><option value="0">JNO</option><option value="1">JYES</option></field>';
            }

            $oItem->xml_export = htmlentities($sXMLExport);

            $oItem->xml_export_html = $sXMLExport;
        }

        return $oItem;
    }

    public function setOrderingField($iFieldId) {
        $aField = $this->getItem($iFieldId);
        
        $oDb = JFactory::getDbo();
        $oQuery = $oDb->getQuery(true);
        $oQuery->clear()
                ->update($oDb->quoteName('#__auto_field'))
                ->set($oDb->quoteName('is_ordering_field') . ' = 0')
                ->where($oDb->quoteName('id') . ' <> ' . $oDb->quote($iFieldId))
                ->where($oDb->quoteName('table_id') . ' = ' . (int) $aField->table_id);
        
        $oDb->setQuery($oQuery);
        try {
            $oDb->execute();
        } catch (RuntimeException $e) {
            JError::raiseWarning(500, $oDb->getMessage());
            return $oDb->getMessage();
        }
        
        $oQuery->clear()
                ->update($oDb->quoteName('#__auto_field'))
                ->set($oDb->quoteName('is_ordering_field') . ' = NOT ' . $oDb->quoteName('is_ordering_field'))
                ->where($oDb->quoteName('id') . ' = ' . $oDb->quote($iFieldId));
        
        $oDb->setQuery($oQuery);
        try {
            $oDb->execute();
        } catch (RuntimeException $e) {
            JError::raiseWarning(500, $oDb->getMessage());
            return $oDb->getMessage();
        }
        
        return ($aField->is_ordering_field == 1 ? 0 : 1);
    }

}
